package com.phone.wxtoken;

import com.phone.utils.TextUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by tisen on 2017/8/29.
 */
public class TokenThread {

    private String APPID = "wx5625f36342c1f4c7";
    private String APPSECRET = "30c1f8634ee1f21247b565395a1d45a8";
    private static int COMPLETE_TIME = 7000;
    private static int ERROR_TIME = 120;

    private DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    protected final Log log = LogFactory.getLog(getClass());
    private boolean flag = true;
    private TokenCallBack callBack = new TokenCallBack() {
        @Override
        public void onComplete() {
            if (!flag) {
                flag = true;
                stop();
                service.scheduleAtFixedRate(runnable, 0, COMPLETE_TIME, TimeUnit.SECONDS);
            }
        }

        @Override
        public void onError() {
            if (flag) {
                flag = false;
                stop();
                service.scheduleAtFixedRate(runnable, 0, ERROR_TIME, TimeUnit.SECONDS);
            }
        }
    };
    private ScheduledExecutorService service;

    private Token accessToken = null;
    private TokenError error = null;


    public TokenThread() {
        service = Executors.newSingleThreadScheduledExecutor();
    }

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                accessToken = CommonUtil.getToken(APPID, APPSECRET);
                callBack.onComplete();
            } catch (Exception e) {
                if (e instanceof TokenException) {
                    accessToken = null;
                    error = ((TokenException) e).getError();
                    if (log.isInfoEnabled()) {
                        log.info(format.format(new Date()) + "appid = " + APPID + " | appsecret = " + APPSECRET + "\n\t\t\t" + error.toString());
                    }
                }
                callBack.onError();
                e.printStackTrace();
            }
        }
    };


    public void start() {
        service.scheduleAtFixedRate(runnable, 0, COMPLETE_TIME, TimeUnit.SECONDS);
    }

    public void stop() {
        service.execute(runnable);
    }

    public void refresh() {
        service.execute(runnable);
        start();
    }

    public Token getAccessToken() {
        return accessToken;
    }

    public TokenError getError() {
        return error;
    }

    public void setAPPID(String APPID) {
        if (!TextUtil.textIsEmpty(APPID))
            this.APPID = APPID;
    }

    public void setAPPSECRET(String APPSECRET) {
        if (!TextUtil.textIsEmpty(APPSECRET))
            this.APPSECRET = APPSECRET;
    }

    public void setCallBack(TokenCallBack callBack) {
        this.callBack = callBack;
    }

    public interface TokenCallBack {
        void onComplete();

        void onError();
    }
}
